package com.cqie.hospitalescort.service.file;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.StorageClass;
import com.cqie.hospitalescort.config.AliYunOssConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 文件上传下载功能
 */
@Service
public class AliYunServiceImpl implements AliYunService {

    @Autowired
    private AliYunOssConfig aliYunOss;

    /**
     * 上传多个文件至OSS，并返回文件的访问URL列表
     *
     * @param files 文件列表
     * @return 文件的访问URL列表
     */
    public List<String> uploadFiles(List<MultipartFile> files) throws IOException {
        List<String> urls = new ArrayList<>();
        OSS ossClient = null;
        try {
            ossClient = new OSSClientBuilder().build(aliYunOss.getEndpoint(), aliYunOss.getAccessKeyId(), aliYunOss.getAccessKeySecret());
            for (MultipartFile file : files) {
                String fileName = file.getOriginalFilename();
                if (fileName == null || fileName.isEmpty()) {
                    throw new IOException("文件名为空");
                }

                // 创建PutObjectRequest并设置ContentType和其他元数据
                PutObjectRequest putObjectRequest = new PutObjectRequest(aliYunOss.getBucketName(), fileName, new ByteArrayInputStream(file.getBytes()));
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
                metadata.setContentDisposition("inline");
                metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
                metadata.setExpirationTime(new Date(24 * 60 * 60 * 1000));
                putObjectRequest.setMetadata(metadata);

                // 上传文件
                ossClient.putObject(putObjectRequest);
                // 上传文件后设置文件ACL为公共读
                ossClient.setObjectAcl(aliYunOss.getBucketName(), fileName, CannedAccessControlList.PublicRead);


                // 返回文件的访问URL
                urls.add(generateUrl(fileName));
            }
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return urls;
    }


    /**
     * 根据文件的访问URL列表删除OSS中的文件
     *
     * @param fileUrls 文件的访问URL列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteFilesByUrl(List<String> fileUrls) {
        OSS ossClient = null;
        try {
            ossClient = new OSSClientBuilder().build(aliYunOss.getEndpoint(), aliYunOss.getAccessKeyId(), aliYunOss.getAccessKeySecret());
            for (String fileUrl : fileUrls) {
                String fileName = extractFileNameFromUrl(fileUrl);
                if (fileName != null) {
                    ossClient.deleteObject(aliYunOss.getBucketName(), fileName);
                } else {
                    throw new IllegalArgumentException("无法从URL中解析出文件名: " + fileUrl);
                }
            }
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 根据文件名生成访问URL
     *
     * @param fileName 文件名
     * @return 文件的访问URL
     */
    private String generateUrl(String fileName) {
        return "https://" + aliYunOss.getBucketName() + "." + aliYunOss.getEndpoint().replaceFirst("http[s]?://", "") + "/" + fileName;
    }

    /**
     * 从文件的访问URL中提取文件名
     *
     * @param fileUrl 文件的访问URL
     * @return 文件名
     */
    private String extractFileNameFromUrl(String fileUrl) {
        try {
            URL url = new URL(fileUrl);
            String path = url.getPath();
            return path.substring(path.lastIndexOf('/') + 1);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }

}
